package panda.syntax;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import panda.query.condition.Sentence;
import panda.query.condition.ValueExpression;
import panda.query.struct.Attribute;
import panda.query.struct.SemAttribute;

public class SelectStm extends Statement {
	public ArrayList<ValueExpression> attrs;//If the collection is null, then we project all(*).
	private Collection<TblRef> tables;
	private Sentence whereCond, havingCond;
	
	public boolean distinct;
	public List<ColumnName> groupbyCol;
	public List<ColumnName> orderbyCol;
	public List<Boolean> ascOrder;
	
	public ArrayList<Attribute> groupbySem = new ArrayList<Attribute>();
	public ArrayList<Attribute> orderbySem = new ArrayList<Attribute>();
	
	public ArrayList<AggAttr> aggSem = new ArrayList<AggAttr>();
	public ArrayList<Attribute> fixedAttr = new ArrayList<Attribute>();
	public ArrayList<Attribute> selectAttr = new ArrayList<Attribute>();
	
	public boolean star = false;
	
		
	public SelectStm(ArrayList<ValueExpression> attrs, Collection<TblRef> tables, Sentence wCond, boolean Distinct, List<ColumnName> g, Sentence hCond, List<ColumnName> o, List<Boolean> asc) {
		this.attrs = attrs;
		this.tables = tables;
		this.whereCond = wCond;
		this.havingCond=hCond;
		distinct=Distinct;
		groupbyCol=g; orderbyCol=o;
		ascOrder=asc;
	}
//	public Collection<ValueExpression> getAttributes() {
//		return this.attrs;
//	}
	
	public Collection<TblRef> getTables() {
		return this.tables;
	}
	
	public Sentence getWhereCondition() {
		return whereCond;
	}
	public Sentence getHavingCondition() {
		return havingCond;
	}
	
	public SemAttribute findAggregate(Attribute bound, int func) {
		for (AggAttr i : aggSem)
			if (i.bound == bound && i.func == func)
				return i.newattr;
		
		AggAttr a = new AggAttr(bound, func);
		aggSem.add(a);
		return a.newattr;
	}
	
	private static String getAggFN(String org, int agg) {
		switch (agg) {
			case AttributeValue.AVG : return "AVG(" + org + ")";
			case AttributeValue.MAX : return "MAX(" + org + ")";
			case AttributeValue.MIN : return "MIN(" + org + ")";
			case AttributeValue.SUM : return "SUM(" + org + ")";
			case AttributeValue.COUNT: return "COUNT(" + org + ")";
		}
		return null;
	}
	
	public class AggAttr {
		public int func;
		public Attribute bound;
		public SemAttribute newattr;
		
		AggAttr(Attribute bound, int func) {
			this.bound = bound;
			this.func = func;
			this.newattr = new SemAttribute(getAggFN(bound.getAttributeName(), func), bound);
		}
	}
}
